home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
LISP
/
XLISP
/
XLISP21S
/
sources
/
c
/
xlsym
< prev
next >
Wrap
Text File
|
1992-04-25
|
9KB
|
383 lines
/* xlsym - symbol handling routines */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern LVAL obarray,s_unbound;
extern LVAL xlenv,xlfenv;
extern LVAL true; /* Bug fix TAA */
/* forward declarations */
#ifdef ANSI
LVAL NEAR findprop(LVAL sym, LVAL prp);
#else
FORWARD LVAL findprop();
#endif
/* xlenter - enter a symbol into the obarray */
LVAL xlenter(name)
char *name;
{
LVAL sym,array;
int i;
/* check for symbol already in table */
array = getvalue(obarray);
i = hash(name,HSIZE);
for (sym = getelement(array,i); !null(sym); sym = cdr(sym))
if (STRCMP(name,getstring(getpname(car(sym)))) == 0)
return (car(sym));
/* make a new symbol node and link it into the list */
xlsave1(sym);
sym = consd(getelement(array,i));
rplaca(sym,xlmakesym(name));
setelement(array,i,sym);
xlpop();
/* return the new symbol */
return (car(sym));
}
/* xlmakesym - make a new symbol node */
LVAL xlmakesym(name)
char *name;
{
LVAL sym;
sym = cvsymbol(name);
if (*name == ':') {
setvalue(sym,sym);
setsflags(sym, F_CONSTANT);
}
else setsflags(sym, F_NORMAL);
return (sym);
}
/* xlgetvalue - get the value of a symbol (with check) */
LVAL xlgetvalue(sym)
LVAL sym;
{
LVAL val;
/* look for the value of the symbol */
while ((val = xlxgetvalue(sym)) == s_unbound)
xlunbound(sym);
/* return the value */
return (val);
}
/* xlxgetvalue - get the value of a symbol */
LVAL xlxgetvalue(sym)
LVAL sym;
{
register LVAL fp,ep;
LVAL val;
/* check the environment list */
for (fp = xlenv; !null(fp); fp = cdr(fp))
/* check for an instance variable */
if (!null(ep = car(fp)) && objectp(car(ep))) {
if (xlobgetvalue(ep,sym,&val))
return (val);
}
/* check an environment stack frame */
else {
for (; !null(ep); ep = cdr(ep))
if (sym == car(car(ep)))
return (cdr(car(ep)));
}
/* return the global value */
return (getvalue(sym));
}
/* xlsetvalue - set the value of a symbol */
VOID xlsetvalue(sym,val)
LVAL sym,val;
{
register LVAL fp,ep;
if (constantp(sym)) {
xlnoassign(sym);
/* never returns */
}
/* look for the symbol in the environment list */
for (fp = xlenv; !null(fp); fp = cdr(fp))
/* check for an instance variable */
if (!null(ep = car(fp)) && objectp(car(ep))) {
if (xlobsetvalue(ep,sym,val))
return;
}
/* check an environment stack frame */
else {
for (; !null(ep); ep = cdr(ep))
if (sym == car(car(ep))) {
rplacd(car(ep),val);
return;
}
}
/* store the global value */
setvalue(sym,val);
}
/* xlgetfunction - get the functional value of a symbol (with check) */
LVAL xlgetfunction(sym)
LVAL sym;
{
LVAL val;
/* look for the functional value of the symbol */
while ((val = xlxgetfunction(sym)) == s_unbound)
xlfunbound(sym);
/* return the value */
return (val);
}
/* xlxgetfunction - get the functional value of a symbol */
LVAL xlxgetfunction(sym)
LVAL sym;
{
register LVAL fp,ep;
/* check the environment list */
for (fp = xlfenv; !null(fp); fp = cdr(fp))
for (ep = car(fp); !null(ep); ep = cdr(ep))
if (sym == car(car(ep)))
return (cdr(car(ep)));
/* return the global value */
return (getfunction(sym));
}
/* xlsetfunction - set the functional value of a symbol */
VOID xlsetfunction(sym,val)
LVAL sym,val;
{
register LVAL fp,ep;
/* look for the symbol in the environment list */
for (fp = xlfenv; !null(fp); fp = cdr(fp))
for (ep = car(fp); !null(ep); ep = cdr(ep))
if (sym == car(car(ep))) {
rplacd(car(ep),val);
return;
}
/* store the global value */
setfunction(sym,val);
}
/* xlgetprop - get the value of a property */
LVAL xlgetprop(sym,prp)
LVAL sym,prp;
{
LVAL p;
return (null(p = findprop(sym,prp)) ? NIL : car(p));
}
/* xlputprop - put a property value onto the property list */
VOID xlputprop(sym,val,prp)
LVAL sym,val,prp;
{
LVAL pair;
if (!null(pair = findprop(sym,prp)))
rplaca(pair,val);
else
setplist(sym,cons(prp,cons(val,getplist(sym))));
}
/* xlremprop - remove a property from a property list */
VOID xlremprop(sym,prp)
LVAL sym,prp;
{
LVAL last,p;
last = NIL;
for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(last)) {
if (car(p) == prp)
if (!null(last))
rplacd(last,cdr(cdr(p)));
else
setplist(sym,cdr(cdr(p)));
last = cdr(p);
}
}
/* findprop - find a property pair */
LOCAL LVAL NEAR findprop(sym,prp)
LVAL sym,prp;
{
LVAL p;
for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(cdr(p)))
if (car(p) == prp)
return (cdr(p));
return (NIL);
}
/* hash - hash a symbol name string */
int hash(str,len)
char FAR *str;
int len;
{
int i;
for (i = 0; *str; )
i = (i << 2) ^ *str++;
i %= len;
return (i < 0 ? -i : i);
}
/* xlhash -- hash any xlisp object */
/* TAA extension */
int xlhash(obj,len)
LVAL obj;
int len;
{
int i;
unsigned long tot;
union {FIXTYPE i; float j; unsigned FIXTYPE k;} swizzle;
hashloop: /* iterate on conses */
switch (ntype(obj)) {
case SYMBOL:
obj = getpname(obj);
case STRING:
return hash(getstring(obj),len);
case SUBR: case FSUBR:
return getoffset(obj) % len;
case FIXNUM:
swizzle.i = getfixnum(obj);
return (int) (swizzle.k % len);
case FLONUM:
swizzle.j = getflonum(obj);
return (int) (swizzle.k % len);
case CHAR:
return getchcode(obj) % len;
case CONS: case USTREAM:
obj = car(obj); /* just base on CAR */
goto hashloop;
case STREAM:
return 0; /* nothing we can do on this */
default: /* all array types */
for (i = getsize(obj), tot = 0; i-- > 0;)
tot += (unsigned)xlhash(getelement(obj,i),len);
return (int)(tot % len);
}
}
/* unbind a variable/constant */
LVAL xmakunbound()
{
LVAL sym;
sym = xlgasymbol();
xllastarg();
if (constantp(sym))
xlerror("can't unbind constant", sym);
setvalue(sym, s_unbound);
setsflags(sym, F_NORMAL);
return(sym);
}
/* define a constant -- useful in initialization */
VOID defconstant(sym, val)
LVAL sym, val;
{
setvalue(sym, val);
setsflags(sym, F_CONSTANT | F_SPECIAL);
}
/* DEFCONSTANT DEFPARAMETER and DEFVAR */
LVAL xdefconstant()
{
LVAL sym, val;
sym = xlgasymbol();
val = xlgetarg();
xllastarg();
/* evaluate constant value */
val = xleval(val);
if (null(sym)) xlfail("can't redefine NIL");
if (specialp(sym)) {
if (constantp(sym)) {
if (!eql(getvalue(sym),val)) {
errputstr("WARNING-- redefinition of constant ");
errprint(sym);
}
}
else xlerror("can't make special variable into a constant", sym);
}
defconstant(sym, val);
return(sym);
}
LVAL xdefparameter()
{
LVAL sym, val;
sym = xlgasymbol();
val = xlgetarg();
xllastarg();
if (constantp(sym)) xlnoassign(sym);
setvalue(sym, xleval(val));
setsflags(sym, F_SPECIAL);
return(sym);
}
LVAL xdefvar()
{
LVAL sym, val=NIL;
sym = xlgasymbol();
if (moreargs()) {
val = xlgetarg();
xllastarg();
}
if (constantp(sym)) xlnoassign(sym);
if (getvalue(sym) == s_unbound) setvalue(sym, xleval(val));
setsflags(sym, F_SPECIAL);
return(sym);
}
/* xlsinit - symbol initialization routine */
VOID xlsinit()
{
LVAL array,p;
/* initialize the obarray */
obarray = xlmakesym("*OBARRAY*");
array = newvector(HSIZE);
setvalue(obarray,array);
/* add the symbol *OBARRAY* to the obarray */
p = consa(obarray);
setelement(array,hash("*OBARRAY*",HSIZE),p);
}